<!DOCTYPE html>
<html lang="zh-CN" manifest="cache.manifest">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Snaker - 开源轻量级工作流引擎</title>
</head>
<link rel="stylesheet" type="text/css" href="css/bootstrap-responsive.min.css"/>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="css/common.css"/>
<link rel="stylesheet" type="text/css" href="css/shCoreDefault.css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/shCore.js"></script>
<script type="text/javascript" src="js/shBrushXml.js"></script>
<script type="text/javascript" src="js/shBrushJava.js"></script>
<script type="text/javascript">SyntaxHighlighter.all();</script>
<script type="text/javascript">
	window.location.href="http://snakerdoc.jd-app.com/";
</script>
<body>
	<div class="navbar-wrapper">
    	<div class="container">
        	<div class="navbar navbar-inverse">
            	<div class="navbar-inner">
                	<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                   </button>
                   <a class="brand" href="index.html"><img src="img/logo.png"/></a>
                   <div class="nav-collapse collapse">
                    	<ul class="nav">
                  			<li><a href="index.html">首页</a></li>
							<li><a href="quickstart.html">入门</a></li>
							<li><a href="plugin.html">插件</a></li>
							<li><a href="example.html">实例</a></li>
							<li class="active"><a href="integration.html">集成</a></li>
							<li><a href="design.html">设计</a></li>
							<li><a href="business.html">商业计划</a></li>
							<li><a href="donate.html"><img src="img/donate.png"/></a></li>
                        </ul>
                   </div>
                </div>
            </div>
        </div>
    </div>

	<article class="container">
	<section class="row" id="travel" style="margin-top: 80px;">
        <div class="span12 panel" style="display: block;">
        	<div class="row">
            	<div class="span12">
                	<div class="block-left">
					    <h4>集成</h4>
						<p>集成snaker必须在classpath下增加snaker.properties，选择性的配置snaker.xml</p>
						<p>snaker.properties配置明细:</p>
						<table class="table table-bordered">
						  <tr>
						    <th>属性名称</th>
							<th>描述</th>
							<th>默认值</th>
						  </tr>
						  <tr>
						    <td>config</td>
							<td>定义snaker.xml文件的名称</td>
							<td>snaker.xml</td>
						  </tr>
						  <tr>
						    <td>jdbc.pageSize</td>
							<td>查询结果的每页显示数量</td>
							<td>15</td>
						  </tr>
						  <tr>
						    <td>jdbc.*</td>
							<td>如果指定了JDBC+dbutils方式但未提供DataSource时使用</td>
							<td>无</td>
						  </tr>
						  <tr>
						    <td>hibernate.*</td>
							<td>如果指定了Hibernate方式但未提供SessionFactory时使用</td>
							<td>无</td>
						  </tr>
						  <tr>
						    <td>tx.jta.userTransaction</td>
							<td>如果用API集成，并且采用JTA事务时配置</td>
							<td>无</td>
						  </tr>
						</table>
						<p>snaker.properties一般配置如下:</p>
						<pre class="brush: java;">
						config=snaker.xml

						#page must config
						jdbc.pageSize=15
						</pre>
						<p>snaker.xml用于配置自定义扩展，所配置的bean实例属于单例对象，并且存放在ServiceContext上下文中(SimpleContext、SpringContext)，具体配置如下:</p>
						<pre class="brush: xml;">
						&lt;config&gt;
							&lt;!--jdbc的数据库访问与事务拦截器
							&lt;bean class="org.snaker.engine.access.jdbc.JdbcAccess"/&gt;
							&lt;bean class="org.snaker.engine.access.transaction.DataSourceTransactionInterceptor"/&gt;
							--&gt;
							&lt;!-- 
							&lt;bean class="org.snaker.engine.access.transaction.JtaTransactionInterceptor"/&gt;
							 --&gt;
							&lt;!--hibernate3的数据库访问与事务拦截器
							&lt;bean class="org.snaker.engine.access.hibernate3.HibernateAccess"/&gt;
							&lt;bean class="org.snaker.engine.access.transaction.Hibernate3TransactionInterceptor"/&gt;
							--&gt;
							&lt;!--mybatis的数据库访问与事务拦截器
							&lt;bean class="org.snaker.engine.access.mybatis.MybatisAccess"/&gt;
							&lt;bean class="org.snaker.engine.access.transaction.MybatisTransactionInterceptor"/&gt;
							--&gt;
							&lt;!-- 数据库方言配置。如果使用orm框架已自带了方言的支持，这里不需要配置
							&lt;bean class="org.snaker.engine.access.dialect.OracleDialect"/&gt;
							&lt;bean class="org.snaker.engine.access.dialect.MySqlDialect"/&gt;
							&lt;bean class="org.snaker.engine.access.dialect.SQLServerDialect"/&gt;
							 --&gt;
							
							&lt;!-- 任务拦截器，这里可配置多个拦截器，在任务执行后进行拦截处理(如：记录日志、短信提醒等) --&gt;
							&lt;bean class="org.snaker.engine.impl.LogInterceptor"/&gt;

							&lt;!-- 表达式引擎配置 --&gt;
							&lt;bean class="org.snaker.engine.impl.JuelExpression"/&gt;
						&lt;/config&gt;
						</pre>
						<p>snaker.xml不是必须配置的，视具体应用环境而定。<br>
						注：与Spring集成的项目中不需要配置DBAccess、TransactionIntercptor。数据库方言Dialect实现类根据orm框架而定(仅Hibernate框架不需要配置Dialect),
						此处配置的拦截器属于全局拦截器，只要产生Task，就会执行拦截处理。
						</p>

                        <h4>1 Spring集成</h4>
                        <p>Spring集成Snaker时，需要配置流程引擎及服务、事务管理、数据访问方式、缓存管理.具体可参考snaker-web</p>
						<pre class="brush: xml;">
	&lt;!-- 流程引擎配置 --&gt;
	&lt;bean class="org.snaker.engine.spring.SpringSnakerEngine"&gt;
		&lt;property name="processService" ref="processService"/&gt;
		&lt;property name="orderService" ref="orderService"/&gt;
		&lt;property name="taskService" ref="taskService"/&gt;
		&lt;property name="queryService" ref="queryService"/&gt;
		&lt;property name="managerService" ref="managerService"/&gt;
	&lt;/bean&gt;
	
	&lt;bean id="dbAccess" class="org.snaker.engine.access.hibernate.Hibernate3Access"&gt;
		&lt;property name="sessionFactory" ref="sessionFactory"/&gt;
	&lt;/bean&gt;
	
	&lt;bean id="processService" class="org.snaker.engine.core.ProcessService"&gt;
		&lt;property name="access" ref="dbAccess"/&gt;
		&lt;property name="cacheManager" ref="cacheManager"/&gt;
	&lt;/bean&gt;
	&lt;bean id="orderService" class="org.snaker.engine.core.OrderService"&gt;
		&lt;property name="access" ref="dbAccess"/&gt;
	&lt;/bean&gt;
	&lt;bean id="taskService" class="org.snaker.engine.core.TaskService"&gt;
		&lt;property name="access" ref="dbAccess"/&gt;
	&lt;/bean&gt;
	&lt;bean id="managerService" class="org.snaker.engine.core.ManagerService"&gt;
		&lt;property name="access" ref="dbAccess"/&gt;
	&lt;/bean&gt;
	&lt;bean id="queryService" class="org.snaker.engine.core.QueryService"&gt;
		&lt;property name="access" ref="dbAccess"/&gt;
	&lt;/bean&gt;
	
	&lt;bean id="cacheManager" class="org.snaker.engine.cache.memory.MemoryCacheManager"/&lt;

	&lt;!-- 流程事务配置 aop的pointcut中增加:or execution(* org.snaker.engine..*.*(..))--&gt;
	&lt;tx:attributes&gt;
		&lt;tx:method name="start*" propagation="REQUIRED"/&gt;
		&lt;tx:method name="execute*" propagation="REQUIRED"/&gt;
		&lt;tx:method name="save*" propagation="REQUIRED"/&gt;
		&lt;tx:method name="delete*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="update*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="remove*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="add*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="assign*" propagation="REQUIRED" /&gt; 
		&lt;tx:method name="create*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="complete*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="finish*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="terminate*" propagation="REQUIRED" /&gt; 
		&lt;tx:method name="take*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="deploy*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="redeploy*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="undeploy*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="withdrawTask*" propagation="REQUIRED" /&gt;
		&lt;tx:method name="native*" propagation="REQUIRED" /&gt;
							
		&lt;tx:method name="get*" propagation="REQUIRED" read-only="true" /&gt;
		&lt;tx:method name="find*" propagation="REQUIRED" read-only="true" /&gt;
		&lt;tx:method name="query*" propagation="REQUIRED" read-only="true" /&gt;
		&lt;tx:method name="search*" propagation="REQUIRED" read-only="true" /&gt;
		&lt;tx:method name="is*" propagation="REQUIRED" read-only="true" /&gt;
	&lt;/tx:attributes&gt;
						</pre>
                        <br>
                        <h5>1.1 SpringJdbc</h5>
						<pre class="brush: xml;">
						&lt;bean id="dbAccess" class="org.snaker.engine.access.spring.SpringJdbcAccess"&gt;
							&lt;property name="dataSource" ref="dataSource"/&gt;
							&lt;property name="lobHandler" ref="lobHandler"/&gt;
						&lt;/bean&gt;
						&lt;bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" /&gt;
						</pre>
                        <br>
                        <h5>1.2 Hibernate</h5>
						<p>需要在sessionFactory的bean配置中增加mappingResources属性</p>
						<pre class="brush: xml;">
						&lt;property name="mappingResources"&gt;
									&lt;list&gt;
										&lt;value&gt;hbm/snaker.task.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.order.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.ccorder.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.process.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.taskactor.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.workitem.hbm.xml&lt;/value&gt;
										&lt;value&gt;hbm/snaker.surrogate.hbm.xml&lt;/value&gt;
									&lt;/list&gt;
						&lt;/property&gt;
						</pre>

						<pre class="brush: xml;">
						&lt;bean id="dbAccess" class="org.snaker.engine.access.hibernate3.HibernateAccess"&gt;
							&lt;property name="sessionFactory" ref="sessionFactory"/&gt;
						&lt;/bean&gt;
						</pre>
                        <br>
                        <h5>1.3 mybatis</h5>
						<pre class="brush: xml;">
						&lt;bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&gt;
							&lt;property name="configLocation" value="classpath:mybatis.cfg.xml"/&gt;
							&lt;property name="dataSource" ref="dataSource" /&gt;
							&lt;property name="typeAliasesPackage" value="org.snaker.engine.entity" /&gt;
						&lt;/bean&gt;
						</pre>

						<pre class="brush: xml;">
						&lt;bean id="dbAccess" class="org.snaker.engine.access.mybatis.MybatisAccess"&gt;
							&lt;property name="sqlSessionFactory" ref="sqlSessionFactory"/&gt;
						&lt;/bean&gt;
						</pre>

						<p>mybatis.cfg.xml配置如下:</p>
						<pre class="brush: xml;">
						&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
						&lt;!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
						"http://mybatis.org/dtd/mybatis-3-config.dtd"&gt;
						&lt;configuration&gt;
							&lt;mappers&gt;
								&lt;mapper resource="mapper/process.xml"/&gt;
								&lt;mapper resource="mapper/order.xml"/&gt;
								&lt;mapper resource="mapper/task.xml"/&gt;
								&lt;mapper resource="mapper/task-actor.xml"/&gt;
								&lt;mapper resource="mapper/hist-order.xml"/&gt;
								&lt;mapper resource="mapper/hist-task.xml"/&gt;
								&lt;mapper resource="mapper/hist-task-actor.xml"/&gt;
								&lt;mapper resource="mapper/query.xml"/&gt;
								&lt;mapper resource="mapper/hist-query.xml"/&gt;
							&lt;/mappers&gt;
						&lt;/configuration&gt;
						</pre>

						<pre class="brush: xml;">
						&lt;bean id="dbAccess" class="org.snaker.engine.access.mybatis.MybatisAccess"&gt;
							&lt;property name="sqlSessionFactory" ref="sqlSessionFactory"/&gt;
						&lt;/bean&gt;
						</pre>
                        <br>
                        <h4>2 API集成</h4>
						<p>如果使用api集成，需要在snaker.xml中配置DBAccess、Transaction、Dialect</p>
						<pre class="brush: java;">
						import javax.sql.DataSource;
						import org.snaker.engine.SnakerEngine;
						import org.snaker.engine.access.jdbc.JdbcHelper;
						import org.snaker.engine.cfg.Configuration;
						public class SnakerHelper {
							private static final SnakerEngine engine;
							static {
								//使用项目中已有的DataSource、SessionFactory、SqlSessionFactory对象
								//传递至initAccessDBObject方法中都可以
								DataSource dataSource = JdbcHelper.getDataSource();
								engine = new Configuration()
									.initAccessDBObject(dataSource)
									.buildSnakerEngine();
							}
							public static SnakerEngine getEngine() {
								return engine;
							}
						}
						</pre>
                        <p>initAccessDBObject方法传递的参数值与snaker.xml配置的数据库访问对应关系：</p>
						<table class="table table-bordered">
						  <tr>
						    <th>参数类型</th>
							<th>访问对象</th>
							<th>事务管理拦截器</th>
							<th>依赖库</th>
						  </tr>
						  <tr>
						    <td>DataSource</td>
							<td>JdbcAccess</td>
							<td>DataSourceTransactionInterceptor</td>
							<td>commons-dbcp-1.4.jar
							<br>commons-dbutils-1.5.jar
							<br>commons-pool-1.5.4.jar
							</td>
						  </tr>
						  <tr>
						    <td>SessionFactory</td>
							<td>HibernateAccess</td>
							<td>Hibernate3TransactionInterceptor</td>
							<td>hibernate-*-3.5.5.jar</td>
						  </tr>
						  <tr>
						    <td>SqlSessionFactory</td>
							<td>MybatisAccess</td>
							<td>MybatisTransactionInterceptor</td>
							<td>mybatis-3.2.3.jar</td>
						  </tr>
						</table>
						<p>initAccessDBObject方法也可以不调用，而使用snaker.properties中的jdbc.*或hibernate.*来初始化DataSource、SessionFactory、SqlSessionFactory。但在实际的项目，还是建议使用该项目已有的访问对象</p>
                        <br>

						<h4>3 Jfinal集成</h4>
						<p>在Jfinal平台中集成Snaker，可按照如下步骤操作：</p>
						<br>
						<h5>3.1 增加maven依赖或jar</h5>
						<p>snaker-jfinal的maven坐标为：</p>
						<pre class="brush: xml;">
							&lt;dependency&gt;
								&lt;groupId&gt;com.github.snakerflow&lt;/groupId&gt;
								&lt;artifactId&gt;snaker-jfinal&lt;/artifactId&gt;
								&lt;version&gt;2.0.0&lt;/version&gt;
							&lt;/dependency&gt;
						</pre>
						<p>如果非maven项目，则需要在百度网盘上下载snaker-jfinal-***.jr</p>
						<br>
						<h5>3.2 配置插件SnakerPlugin</h5>
						<pre class="brush: java;">
						import org.snaker.jfinal.plugin.SnakerPlugin;
						......

						/**
						 * 配置插件
						 */
						public void configPlugin(Plugins me) {
							// 配置C3p0数据库连接池插件
							C3p0Plugin c3p0Plugin = new C3p0Plugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password").trim());
							me.add(c3p0Plugin);
							
							// 配置ActiveRecord插件
							ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
							me.add(arp);
							arp.addMapping("blog", Blog.class);	// 映射blog 表到 Blog模型
							
							// 配置Snaker插件
							SnakerPlugin snakerPlugin = new SnakerPlugin(c3p0Plugin);
							me.add(snakerPlugin);
						}
						</pre>
						<br>
						<h5>3.3 配置Jfinal方式的DBAccess、事务拦截器</h5>
                        <p>在snaker.xml中配置数据库访问类路径：</p>
						<pre class="brush: xml;">
						&lt;bean class="org.snaker.jfinal.access.JfinalAccess"/&gt;
						&lt;bean class="org.snaker.jfinal.access.JfinalTransactionInterceptor"/&gt;
						</pre>
						<br>
						<h5>3.4 使用</h5>
						<pre class="brush: java;">
						//直接从SnakerPlugin的静态方法getEngine获得引擎实现类，再调用其API进行操作即可
						SnakerPlugin.getEngine().startInstanceByName("simple", null, "test", args);
						</pre>
                        <br>
                    </div>
                </div>
			</div>
        </div>
    </section>
    </article>
    <div class="container marketing">
		<footer>
			<p>&copy; 2013-2015 Snaker 皖ICP备14011739号</p>
		</footer>    
    </div>
	<script type="text/javascript">
		var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
		document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F89978c29a2dac2a973c76424425ead4f' type='text/javascript'%3E%3C/script%3E"));
	</script>
</body>
</html>
